# -*- coding: utf-8 -*-
"""
Created on Wed Jan 11 11:40:47 2023

@author: xtp

"""
from hyperimage import HyperImage
from smalltools import Files, Table, Read, Tools
from dataprocess import DataLoad, PreProcessing, FeatureSelection, QualitativeAnalysis
from tqdm import tqdm
import time
import pandas as pd
import numpy as np
from sklearn.metrics import classification_report
import warnings
import concurrent.futures
import time

warnings.filterwarnings("ignore")

path_result = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data'
ext_result = ['*.csv']
path_train = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data\train.csv'
path_test = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data\test.csv'

df_train_org = pd.read_csv(path_train, header=[0, 1], index_col=[0], sep=',')
df_train_org = df_train_org.sort_index(axis=1, level=0, ascending=False)
df_test_org = pd.read_csv(path_test, header=[0, 1], index_col=[0], sep=',')
df_test_org = df_test_org.sort_index(axis=1, level=0, ascending=False)
# train_x = np.array(df_train_org.values).astype(np.float64)
# test_x = np.array(df_test_org.values).astype(np.float64)
# train_y = np.array(df_train_org.index).astype(np.int64)
# test_y = np.array(df_test_org.index).astype(np.int64)

def diff_list(lst_length, step=5):
    start = step
    num = int(lst_length/step)
    stop = num*step
    diff_list = np.linspace(start=start, stop=stop, num=num).astype(np.int64)
    return diff_list

diff_list = diff_list(len(df_train_org.columns), step=5)

# %% GridSearchCV
result_features_G = []
for n_features in tqdm(diff_list, position=0, ncols=75, leave=True, total=len(diff_list), desc='Total progress', colour='green'):
    df_train = df_train_org.iloc[:, :n_features]
    df_test = df_test_org.iloc[:, :n_features]
    qa = QualitativeAnalysis(df_train, df_test, method='PLS-DA')
    estimator = qa.getEstimator()
    spaces = qa.getSpaces()
    params = qa.getParams()
    result_G, best_model_G, y_pred_test_G, best_acc_train_G, best_acc_test_G \
        = qa.GridsearchCV(cv=10)
    result_feature_G = [n_features, result_G, best_model_G, y_pred_test_G,
                        best_acc_train_G, best_acc_test_G]
    result_features_G.append(result_feature_G)
result_features_G_df = pd.DataFrame(result_features_G, columns=['n_features', 'result',
                                                                'best_model', 'y_pred_test', 'best_acc_train', 'best_acc_test']
                                    ).sort_values(by='best_acc_train', ascending=False).reset_index(drop=True)
best_n_features_G = result_features_G_df.loc[0, 'n_features']
best_y_pred_G = result_features_G_df.loc[0, 'y_pred_test']
best_result_G = qa.GridsearchCV_test(result_features_G_df.loc[0, 'result'])
qa.GridsearchCV_visualize(best_result_G)

# %% BayesSearchCV
result_features_B = []
for n_features in tqdm(diff_list, position=0, ncols=80, leave=True, total=len(diff_list), desc='Total progress', colour='green'):
    df_train = df_train_org.iloc[:, :n_features]
    df_test = df_test_org.iloc[:, :n_features]
    qa = QualitativeAnalysis(df_train, df_test, method='RF')
    estimator = qa.getEstimator()
    spaces = qa.getSpaces()
    params = qa.getParams()
    result_B, best_model_B, y_pred_test_B, best_acc_train_B, best_acc_test_B \
        = qa.BayessearchCV(n_iter=100, cv=10)
    result_feature_B = [n_features, result_B, best_model_B, y_pred_test_B,
                        best_acc_train_B, best_acc_test_B]
    result_features_B.append(result_feature_B)
    
result_features_B = pd.DataFrame(result_features_B, columns=['n_features', 'result',
                                                             'best_model', 'y_pred_test', 'best_acc_train', 'best_acc_test']
                                 ).sort_values(by='best_acc_train', ascending=False).reset_index(drop=True)
result_B_df = QualitativeAnalysis.BayessearchCV_visualize(
    result_features_B.loc[0, 'result'])

# %% BayesianOptimization
begin_time = time.time()
result_features_BO = []
for n_features in tqdm(diff_list, position=0, ncols=75, leave=True, total=len(diff_list), desc='Total progress', colour='green'):
    df_train = df_train_org.iloc[:, :n_features]
    df_test = df_test_org.iloc[:, :n_features]
    qa = QualitativeAnalysis(df_train, df_test, method='SVM')
    estimator = qa.getEstimator()
    spaces = qa.getSpaces()
    params = qa.getParams()
    result_BO, best_model_BO, y_pred_test_BO, best_acc_train_BO, best_acc_test_BO \
        = qa.Bayesopt(init_points=10, n_iter=40)
    result_feature_BO = [n_features, result_BO, best_model_BO, y_pred_test_BO,
                         best_acc_train_BO, best_acc_test_BO]
    result_features_BO.append(result_feature_BO)
result_features_BO_df = pd.DataFrame(result_features_BO, columns=['n_features', 
    'result', 'best_model', 'y_pred_test', 'best_acc_train', 'best_acc_test']
     ).sort_values(by='best_acc_train', ascending=False).reset_index(drop=True)
best_n_features_BO = result_features_BO_df.loc[0, 'n_features']
best_y_pred_BO = result_features_BO_df.loc[0, 'y_pred_test']
best_result_BO = result_features_BO_df.loc[0, 'result']
qa.Bayesopt_visualize(best_result_BO)
end_time = time.time()
run_time = round(end_time-begin_time)
hours = run_time//3600
minutes = (run_time-3600*hours)//60
seconds = run_time-3600*hours-60*minutes
print (f'Runing time：{hours} hours {minutes} minutes {seconds} secends')
# %% Model Evaluation
report = classification_report(qa.y_test, best_y_pred_BO)
qa.plot_confusion_matrix(qa.y_test, best_y_pred_BO)
QualitativeAnalysis.multiClassification_PR(qa.y_test, best_y_pred_BO)
QualitativeAnalysis.multiClassification_ROC(qa.y_test, best_y_pred_BO)

# %% Progress bar
process = Files(path_result, ext_result, flag='all')
process1 = tqdm(range(3), position=0, ncols=80, leave=True, total=len(range(3)),
                desc='Total progress', colour='green')
for i in process1:
    process2 = tqdm(range(3), position=0, ncols=80, leave=False, total=len(range(3)),
                    desc='Outlier Check & DataLoad', colour='blue')
    for i1 in process2:
        time.sleep(1)

        process3 = tqdm(range(3), position=0, ncols=80, leave=False, total=len(range(3)),
                        desc='Preprocess & Feature Selection'+str(i1), colour='magenta')
        for i2 in process3:
            time.sleep(1)

    print(' —— loop ' + str(i+1) + '\n')

"BLACK, RED, GREEN, BLUE, MAGENTA, CYAN, WHITE"

# %% preprocess
from hyperimage import HyperImage
from smalltools import Files, Table, Read, Tools
from dataprocess import DataLoad, PreProcessing, FeatureSelection, QualitativeAnalysis
from tqdm import tqdm
import time
import pandas as pd
import numpy as np
from sklearn.metrics import classification_report
import warnings
import concurrent.futures
import time
path = r'D:\Python\Processing\3.csv'
df = pd.read_csv(path, header=[0], index_col=None, sep=',')
p = PreProcessing(df)
dff = p.PreProcess(methods=['SG','MSC','D2'], return2data=True)
dff.to_csv(r'D:\Python\Processing\7d-D20.csv')


# %% test
path = r'D:\Python\Processing\1.csv'
train_mr = pd.read_csv(path, header=[0,1], index_col=[0], sep=',')
path1 = r'D:\Python\Processing\2.csv'
test_mr = pd.read_csv(path1, header=[0], index_col=[0], sep=',')

bands = [columns[1] for columns in list(train_mr.columns)]
test_mr = test_mr.loc[:, bands]
test_mr.columns = train_mr.columns


# %% pytorch_11.6
import torch as tc
import numpy as np
y = tc.tensor([1])
y = y.to(device = 'cuda')
print('y =', y)
print('y.shape =', y.shape)
print('y.numel()=', y.numel())
print('y.ndimension()=', y.ndimension())
print('type(y)=', type(y))
print('y.dtype =', y.dtype)
print('y.device =', y.device)

I = tc.eye(2)
print('I=', I)
J = I
J[1, 1] = -1
print('I=', I)
print('J=', J)

device = tc.device("cuda:0" if tc.cuda.is_available() else "cpu")
print(device)

from hyperimage import HyperImage
from smalltools import Files, Table, Read, Tools
from dataprocess import DataLoad, PreProcessing, FeatureSelection, QualitativeAnalysis
from tqdm import tqdm
import time
import pandas as pd
import numpy as np
from sklearn.metrics import classification_report
import warnings
import concurrent.futures
import time

warnings.filterwarnings("ignore")

path_result = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data'
ext_result = ['*.csv']
path_train = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data\train.csv'
path_test = r'D:\Repository\phenotype-data-processing\Jupyter-Notebook\test-data\test.csv'

df_train_org = pd.read_csv(path_train, header=[0, 1], index_col=[0], sep=',')
df_train_org = df_train_org.sort_index(axis=1, level=0, ascending=False)
df_test_org = pd.read_csv(path_test, header=[0, 1], index_col=[0], sep=',')
df_test_org = df_test_org.sort_index(axis=1, level=0, ascending=False)

def diff_list(lst_length, step=5):
    start = step
    num = int(lst_length/step)
    stop = num*step
    diff_list = np.linspace(start=start, stop=stop, num=num).astype(np.int64)
    return diff_list

diff_list = diff_list(len(df_train_org.columns), step=20)

result_features_B = []
for n_features in tqdm(diff_list, position=0, ncols=80, leave=True, total=len(diff_list), desc='Total progress', colour='green'):
    df_train = df_train_org.iloc[:, :n_features]
    df_test = df_test_org.iloc[:, :n_features]
    qa = QualitativeAnalysis(df_train, df_test, method='RF')
    estimator = qa.getEstimator()
    spaces = qa.getSpaces()
    params = qa.getParams()
    result_B, best_model_B, y_pred_test_B, best_acc_train_B, best_acc_test_B \
        = qa.BayessearchCV(n_iter=100, cv=10)
    result_feature_B = [n_features, result_B, best_model_B, y_pred_test_B,
                        best_acc_train_B, best_acc_test_B]
    result_features_B.append(result_feature_B)
    
result_features_B = pd.DataFrame(result_features_B, columns=['n_features', 'result',
                                                             'best_model', 'y_pred_test', 'best_acc_train', 'best_acc_test']
                                 ).sort_values(by='best_acc_train', ascending=False).reset_index(drop=True)
result_B_df = QualitativeAnalysis.BayessearchCV_visualize(
    result_features_B.loc[0, 'result'])

# %% diff_list
step = 5
lst_length = 127
start = step + 5
num = int(lst_length/step)
stop = num*step
diff_list = np.linspace(start=start, stop=stop, num=num).astype(np.int64)
print(diff_list)
